﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using Medianamik.Globalization;

namespace Medianamik.Core.Synchronization
{
    public static class RecordTypeToNodeTypeConverter
    {

        public static NodeType Convert(this RecordType source, 
            ICollection<Translation> translations)
        {
            return source.Convert(translations, null, null);
        }

        public static NodeType Convert(this RecordType source,
            ICollection<Translation> translations, Guid? typeId, string name)
        {
            var newType = new NodeType(typeId ?? source.Id ?? Guid.NewGuid(),
                name ?? source.Name, source.IsInheritable,
                            source.IsGenerated, source.IsAbstract, source.IsSystem,
                            source.ParentId, source.IsManyToMany,
                            source.LegitimateParentRecordTypeIds.Select(rt => new NodeType(rt)).ToList(),
                            source.LegitimateParentRecordIds.Select(r => new Node(r)).ToList(),
                            source.Templates.Select(rtt =>
                                new TypeTemplate()
                                {
                                    TemplateId = rtt.TemplateId,
                                    NodeTypeId = source.Id,
                                    WebSiteId = rtt.WebSiteId
                                }).ToList())
            {
                Indexable = source.IsIndexable,
                Listable = source.IsListable,
                Description = source.Description,
                ExtendedProperties = new NodeTypeExtendedProperties(source.ExtendedProperties),
                IsVersioned = source.IsVersioned,
            };
            
            if (translations != null)
                translations.Add(source.LocalizedNames);

            //Propriétés
            foreach (var property in source.Properties)
            {
                property.AddToType(newType, translations, typeId.HasValue ? 
                    Guid.NewGuid() : default(Nullable<Guid>));
            }

            return newType;
        }

        public static void AddToType(this RecordTypeProperty recordTypeProperty, NodeType type, 
            ICollection<Translation> translations)
        {
            recordTypeProperty.AddToType(type, translations, null);
        }

        public static void AddToType(this RecordTypeProperty recordTypeProperty, NodeType type,
            ICollection<Translation> translations, Guid? propertyId)
        {
            var medianamikControlSettings = new MedianamikControlInfo(new Unit(recordTypeProperty.MedianamikControlWidth)
                                              , recordTypeProperty.MedianamikControlHeight
                                              , recordTypeProperty.RootNodeId);


            var validationRegex = string.IsNullOrEmpty(recordTypeProperty.RegexValidation)
                      ? null : new Regex(recordTypeProperty.RegexValidation);

            var property = new NodeTypeProperty(propertyId ?? recordTypeProperty.Id,
                recordTypeProperty.Name,
                recordTypeProperty.MaxLength,
                recordTypeProperty.MinLength,
                type.ID,
                recordTypeProperty.HasTooltip,
                recordTypeProperty.IsLanguageNeutral,
                recordTypeProperty.IsRequired,
                recordTypeProperty.ValueMustBeUnique,
                validationRegex,
                recordTypeProperty.GroupName,
                recordTypeProperty.MedianamikControlId,
                medianamikControlSettings,
                recordTypeProperty.IsLookup ? DataTypes.UniqueIdentifier : recordTypeProperty.DataTypeId,
                recordTypeProperty.IsLookup ? recordTypeProperty.PrimaryTypeId : null,
                recordTypeProperty.IsLookup ? recordTypeProperty.PrimaryPropertyId : null,
                null, null, null) //TODO: On ne supporte pas les types many-to-many
            {
                Roles = new RoleCollection(recordTypeProperty.Roles),
                Flags = new BitVector32(recordTypeProperty.Flags),
                Description = recordTypeProperty.Description
            };

            type.PropertiesInternal.Add(property);
            property.IsNew = true;

            if(translations != null)
                translations.Add(recordTypeProperty.LocalizedNames);
        }
    }
}
